/*
 * Copyright (c) 2020, Yanhui Shi <lime.syh at gmail dot com>
 * All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef LIBCSP_COMMON_H
#define LIBCSP_COMMON_H

#ifdef __cplusplus
extern "C" {
#endif

#define csp_likely(x)     __builtin_expect(!!(x), 1)
#define csp_unlikely(x)   __builtin_expect(!!(x), 0)
#define csp_soft_mbarr()  __asm__ __volatile__("" ::: "memory")

#define csp_swap(a, b)                                                         \
  do { typeof(a) tmp = (a); (a) = (b); (b) = tmp; } while (0)

#define csp_exp(num) ({                                                        \
  size_t exp = 0;                                                              \
  if ((num) > 0) {                                                             \
    size_t tmp = (num);                                                        \
    while (tmp != 1) {                                                         \
      exp++;                                                                   \
      tmp >>= 1;                                                               \
    }                                                                          \
    if ((1 << exp) != (num)) {                                                 \
      exp++;                                                                   \
    }                                                                          \
  }                                                                            \
  exp;                                                                         \
})                                                                             \

#ifdef __cplusplus
}
#endif

#endif
